﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using BbsbWebService.Classes;
using BbsbWebService.Enums;
using System.ServiceModel.Web;
using BbsbWebService.Tasks;
using BbsbWebService.Classes.Plugins.Bbsb;
using BbsbWebService.Classes.Plugins.KeyMap;

namespace BbsbWebService.Service
{
    [ServiceContract]
    [ServiceKnownType("AllServiceKnownTypes", typeof(AppSettings))]
    public interface IBbsbService
    {
        /// <summary>
        /// Retrieves an array of all the controllable items within the service
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "/allitems")]
        ControllableItem[] GetAllItems();

        /// <summary>
        /// Gets a specific item from the service based on its Id
        /// </summary>
        /// <param name="id">The Identifier of the item</param>
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "/item?id={id}")]
        ControllableItem GetItem(Guid id);

        /// <summary>
        /// Gets basic information on all the Groups that are of a specific type
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "/groups?filter={filter}")]
        BaseGroup[] GetGroups(GroupType filter);

        /// <summary>
        /// Gets full information on all the Groups that are of a specific type
        /// </summary>
        /// <param name="filter"></param>
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "/detailedgroups?filter={filter}")]
        Group[] GetDetailedGroups(GroupType filter);

        /// <summary>
        /// Gets a specific Group based on its Identifier
        /// </summary>
        /// <param name="id">The unique identifier of the group</param>
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "/group?id={id}")]
        Group GetGroup(Guid id);

        /// <summary>
        /// Gets a specific Task based on its Id
        /// </summary>
        /// <param name="id">The unique identifier of the Task</param>
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "/task?id={id}")]
        BaseTask GetTask(Guid id);

        /// <summary>
        /// Gets all the Tasks being served by the service
        /// </summary>
        /// <returns></returns>
        [OperationContract]
        [WebGet(UriTemplate = "/tasks")]
        BaseTask[] GetTasks();

        /// <summary>
        /// Sets a sleep timer to turn a device off
        /// </summary>
        /// <param name="id">The Id of the Item/Group to turn off</param>
        /// <param name="delay">The amount of minutes to delay</param>
        [OperationContract]
        [WebGet(UriTemplate = "/sleep?id={id}&delay={delay}")]
        void Sleep(Guid id, int delay);

        /// <summary>
        /// Sends a power command to a device
        /// </summary>
        /// <param name="id">The Id of the Item/Group to turn off</param>
        /// <param name="option">The option of call (on or off)</param>
        /// <returns>True for success, false otherwise</returns>
        [OperationContract]
        [WebGet(UriTemplate = "/power?id={id}&com={option}")]
        PowerState SendPower(Guid id, PowerOption option);

        /// <summary>
        /// Sends an On command to a specific device/group
        /// </summary>
        /// <param name="id">The Id of the Item/Group</param>
        /// <returns>True for success, false otherwise</returns>
        [OperationContract]
        [WebGet(UriTemplate = "/poweron?id={id}")]
        PowerState PowerOn(Guid id);

        /// <summary>
        /// Sends the Off command to a specific device/group
        /// </summary>
        /// <param name="id">The Id of the Item/Group</param>
        /// <returns>True for success, false otherwise</returns>
        [OperationContract]
        [WebGet(UriTemplate = "/poweroff?id={id}")]
        PowerState PowerOff(Guid id);

        /// <summary>
        /// Toggles the power of an item (if it is unknown it tries to turn it on by default)
        /// </summary>
        /// <param name="id">The Id of the Item</param>
        /// <returns>The new state of the Item</returns>
        [OperationContract]
        [WebGet(UriTemplate = "/toggle?id={id}")]
        PowerState Toggle(Guid id);

        [OperationContract]
        [WebGet(UriTemplate = "/updateState?id={id}&state={state}")]
        void UpdateState(Guid id, PowerState state);

        /// <summary>
        /// Saves an Item to the service (this can be to update or add an item)
        /// </summary>
        /// <param name="item">The item to save</param>
        [OperationContract]
        [WebInvoke(Method = "INSERT", UriTemplate = "/item")]
        void SaveItem(ControllableItem item);

        /// <summary>
        /// Saves a Group to the service (this can be to update or add a group)
        /// </summary>
        /// <param name="group">The Group to save</param>
        [OperationContract]
        [WebInvoke(Method = "INSERT", UriTemplate = "/group")]
        void SaveGroup(Group group);

        /// <summary>
        /// Saves a Task to the service (this can be to update or add a task)
        /// </summary>
        /// <param name="task">The task to save</param>
        [OperationContract]
        [WebInvoke(Method = "INSERT", UriTemplate = "/task")]
        void SaveTask(BaseTask task);

        /// <summary>
        /// Removes an item from the service
        /// </summary>
        /// <param name="item">The item to be removed</param>
        [OperationContract]
        [WebInvoke(Method = "DELETE", UriTemplate = "/item")]
        void RemoveItem(ControllableItem item);

        /// <summary>
        /// Removes a Group from the service
        /// </summary>
        /// <param name="group">The group to be removed</param>
        [OperationContract]
        [WebInvoke(Method = "DELETE", UriTemplate = "/group")]
        void RemoveGroup(Group group);

        /// <summary>
        /// Removes a Task from the service
        /// </summary>
        /// <param name="task"></param>
        [OperationContract]
        [WebInvoke(Method = "DELETE", UriTemplate = "/task")]
        void RemoveTask(BaseTask task);
    }
}
